# -*- coding: binary -*-
require 'msf/core'

module Msf

###
#
# This module exposes methods for querying a remote DB2 service
#
###
module Exploit::Remote::DB2

  include Exploit::Remote::Tcp

  #
  # Creates an instance of a DB2 exploit module.
  #
  def initialize(info = {})
    super

    # Register the options that all MSSQL exploits may make use of.
    register_options(
      [
        Opt::RHOST,
        Opt::RPORT(50000),
        OptString.new('USERNAME', [ false, 'The username to authenticate as', 'db2inst1']),
        OptString.new('PASSWORD', [ false, 'The password for the specified username', '']),
        OptString.new('DATABASE', [ true, 'The name of the target database', 'toolsdb'])
      ], Msf::Exploit::Remote::DB2)

  end

  #
  # This method sends a TCP query packet to the server, using
  # datastore options and parses out the reply packet
  # into a hash
  #
  def db2_probe(timeout=5)
    disconnect if self.sock
    connect

    probe_packet = Rex::Proto::DRDA::Utils.client_probe(datastore['DATABASE'])
    sock.put probe_packet
    resp = sock.get_once

    return {} if not resp
    return {} if resp.length == 0
    pkt = Rex::Proto::DRDA::SERVER_PACKET.new.read(resp)
    return Rex::Proto::DRDA::Utils.server_packet_info(pkt)
  end

  def db2_check_login(timeout=5)
    probe_data = db2_probe
    return probe_data unless probe_data[:plaintext_auth]
    login_packet = Rex::Proto::DRDA::Utils.client_auth(:dbname => datastore['DATABASE'],
      :dbuser => datastore['USERNAME'],
      :dbpass => datastore['PASSWORD'])
    sock.put login_packet
    resp = sock.get_once
    return {} if not resp
    return {} if resp.length == 0
    pkt = Rex::Proto::DRDA::SERVER_PACKET.new.read(resp)
    return Rex::Proto::DRDA::Utils.server_packet_info(pkt)
  end

end
end
